﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using DR.Repository.Abstract;
using DR.DBDomainModel;

namespace DR.Repository.Concrete.LinqToSql
{
    public class LinqToSqlReportRepository : LinqToSqlBaseRepository<Report, int>, IReportRepository
    {
        public LinqToSqlReportRepository(string connectionString) : base(connectionString)
        {            
        }

        protected override Table<Report> GetDataTable(DataContext dataContext)
        {
            return dataContext.GetTable<Report>();
        }

        protected override System.Linq.Expressions.Expression<Func<Report, bool>> GetIDQuery(int id)
        {
            return r => r.ReportID == id;
        }

        protected override int GetEntityID(Report entity)
        {
            return entity.ReportID;
        }

        protected override DataLoadOptions GetDefaultDataLoadOptions()
        {
            DataLoadOptions loadOptions = new DataLoadOptions();
            loadOptions.LoadWith<Report>(r => r.DeveloperProject);
            loadOptions.LoadWith<DeveloperProject>(r => r.Developer);
            loadOptions.LoadWith<DeveloperProject>(r => r.Project);
            return loadOptions;
        }

        public IList<Report> SelectByDate(DateTime date)
        {
            using (DataContext dc = CreateDataContext())
            {
                return dc.GetTable<Report>().Where(r => r.DateCreate.Date == date.Date).ToList();
            }
        }

        public void DeleteByDate(DateTime date)
        {
            using (DataContext dc = CreateDataContext())
            {
                var tasks = dc.GetTable<Report>().Where(r => r.DateCreate.Date == date.Date);
                dc.GetTable<Report>().DeleteAllOnSubmit(tasks);
                dc.SubmitChanges();
            }
        }

        public Report ChangeState(int id, int state)
        {
            using (DataContext dc = CreateDataContext())
            {
                var entity = dc.GetTable<Report>().SingleOrDefault(r => r.ReportID == id);
                entity.State = state;
                dc.SubmitChanges();
                return entity;
            }
        }


        public IList<Report> SelectByFilter(int? reportPeriodID, int? projectID, int? developerID, ISet<int> includeReportStatuses)
        {
            using (DataContext dc = CreateDataContext())
            {

                if (!reportPeriodID.HasValue)
                {
                    //throw new ArgumentException("reportPeriodID can not be null");
                    return new List<Report>();
                }
                var reports = dc.GetTable<Report>().AsQueryable();
                if (reportPeriodID.HasValue)
                {
                    reports = reports.Where(r => r.ReportingPeriodID == reportPeriodID.Value);
                }
                if (projectID.HasValue)
                {
                    reports = reports.Where(r => r.DeveloperProject.ProjectID == projectID.Value);
                }
                if (developerID.HasValue)
                {
                    reports = reports.Where(r => r.DeveloperProject.DeveloperID == developerID.Value);
                }
                if (includeReportStatuses != null)
                {
                    reports = reports.Where(r => ((IEnumerable<int>)includeReportStatuses).Contains(r.State));
                }
                return reports.ToList();
            }
        }


        public Report ChangeHours(int id, decimal hours)
        {
            using (DataContext dc = CreateDataContext())
            {
                var entity = dc.GetTable<Report>().SingleOrDefault(r => r.ReportID == id);
                entity.Hours = hours;
                entity.DateReporting = DateTime.Now;
                dc.SubmitChanges();
                return entity;
            }
        }
    }
}